/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.core.rootmanager;

import com.inspur.edp.cef.api.changeset.IChangesetManager;
import com.inspur.edp.cef.api.dataType.base.IAccessorCreator;
import com.inspur.edp.cef.api.dataType.entity.ICefEntityContext;
import com.inspur.edp.cef.api.dataType.entity.ICefRootEntity;
import com.inspur.edp.cef.api.manager.IBufferManager;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.api.rootManager.ICefRootManager;
import com.inspur.edp.cef.api.rootManager.IRootEntityCacheManager;
import com.inspur.edp.cef.api.rootManager.IRootManagerContext;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.spi.entity.CefEntityContext;

public abstract class CefRootManager implements ICefRootManager {

  private IRootManagerContext context;

  public final IRootManagerContext getRootContext() {
    if (context == null) {
      context = createRootManagerContext();
      context.setRootManager(this);
    }
    return context;
  }

  protected abstract IRootManagerContext createRootManagerContext();

  protected abstract IChangesetManager createChangesetManager();

  private IChangesetManager changeMgr;

  public IChangesetManager getChangesetManager() {
    if (changeMgr == null) {
      changeMgr = createChangesetManager();
    }
    return changeMgr;
  }

  protected abstract IBufferManager createBufferManager();

  private IBufferManager bufferMgr;

  public IBufferManager getBufferManager() {
    if (bufferMgr == null) {
      bufferMgr = createBufferManager();
    }
    return bufferMgr;
  }

  protected abstract IRootEntityCacheManager createEntityCacheManager();

  private IRootEntityCacheManager entityCacheMgr;

  public IRootEntityCacheManager getEntityCacheManager() {
    if (entityCacheMgr == null) {
      entityCacheMgr = createEntityCacheManager();
    }
    return entityCacheMgr;
  }

  public ICefRootEntity getEntity(String id) {
    return getEntityCacheManager().getEntity(id);
  }

  protected void customInitEntity(ICefRootEntity entity) {
  }

  protected final ICefEntityContext initEntityContext() {
    ICefEntityContext context = createEntityContext();
    customInitEntityContext(context);
    return context;
  }

  protected ICefEntityContext createEntityContext() {
    return new CefEntityContext();
  }

  public void customInitEntityContext(ICefEntityContext context) {
  }

  @Override
  public final ICefRootEntity createEntity(String id) {
    ICefRootEntity entity = newEntity(id);
    ICefEntityContext context = createEntityContext();
    context.setDataType(entity);
    customInitEntityContext(context);
    entity.setContext(context);
    customInitEntity(entity);
    return entity;
  }

  public final ICefRootEntity createSessionlessEntity(String id) {
    ICefRootEntity entity = newEntity(id);
    ICefEntityContext context = createEntityContext();
    context.setDataType(entity);
    customInitSessionlessEntityContext(context);
    entity.setContext(context);
    return entity;
  }

  protected void customInitSessionlessEntityContext(ICefEntityContext context) {
  }

  protected abstract ICefRootEntity newEntity(String id);

  public abstract IAccessorCreator getAccessorCreator();

  public abstract ICefData deserialize(String content);

  public abstract String serialize(ICefData data);

  public abstract IRootRepository getRepository();

  //todo:所有静态化的内容，都使用该内容进行存储下来。
  protected CefRootManagerCacheInfo getMgrCachInfo()
  {return null;}
}
